package org.orarriinae.common.web.result;

import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.orarriinae.common.base.exception.ErrorInfo;
import org.orarriinae.common.utils.constant.StringConstant;

import java.util.List;
import java.util.function.Function;

/**
 * 分页信息返回
 *
 * @author Wang Chengwei
 * @since 1.0
 */
@EqualsAndHashCode(callSuper = true)
@Data
public class PageResponseBean<T> extends BaseResponseBean {
    private List<T> rows;
    private Long page;
    private Integer pageSize;
    private Long pages;
    private Long total;

    /**
     * 返回成功状态，返回分页信息
     *
     * @param page 分页
     * @param <T>  数据类型
     * @return 响应数据包
     */
    public static <T> PageResponseBean<T> success(IPage<T> page) {
        PageResponseBean<T> responseBean = createPageInfo(page);
        responseBean.setSuccess(true);
        responseBean.setErrorCode(StringConstant.SUCCESS_CODE);
        return responseBean;
    }

    /**
     * 返回成功状态，返回分页信息
     *
     * @param page      分页
     * @param extension 扩展数据
     * @param <T>       数据类型
     * @return 响应数据包
     */
    public static <T> PageResponseBean<T> success(IPage<T> page, Object extension) {
        PageResponseBean<T> responseBean = createPageInfo(page);
        responseBean.setExtension(extension);
        responseBean.setSuccess(true);
        responseBean.setErrorCode(StringConstant.SUCCESS_CODE);
        return responseBean;
    }

    /**
     * 返回成功状态，返回分页信息
     *
     * @param page   分页
     * @param mapper 类型转换
     * @param <T>    输入数据类型
     * @param <R>    输出数据类型
     * @return 响应数据包
     */
    public static <T, R> PageResponseBean<R> success(IPage<T> page, Function<? super T, ? extends R> mapper) {
        PageResponseBean<R> responseBean = createPageInfo(page, mapper);
        responseBean.setSuccess(true);
        responseBean.setErrorCode(StringConstant.SUCCESS_CODE);
        return responseBean;
    }

    /**
     * 返回成功状态，返回分页信息
     *
     * @param page      分页
     * @param mapper    类型转换
     * @param extension 扩展数据
     * @param <T>       输入数据类型
     * @param <R>       输出数据类型
     * @return 响应数据包
     */
    public static <T, R> PageResponseBean<R> success(IPage<T> page, Function<? super T, ? extends R> mapper, Object extension) {
        PageResponseBean<R> responseBean = createPageInfo(page, mapper);
        responseBean.setExtension(extension);
        responseBean.setSuccess(true);
        responseBean.setErrorCode(StringConstant.SUCCESS_CODE);
        return responseBean;
    }

    /**
     * 返回错误信息
     *
     * @param errMsg 错误信息
     * @return 响应数据包
     */
    public static PageResponseBean<String> error(String errMsg) {
        PageResponseBean<String> result = new PageResponseBean<>();
        result.setSuccess(false);
        result.setErrorCode(StringConstant.DATA_ERROR);
        result.setMessage(errMsg);
        return result;
    }

    /**
     * 返回错误信息
     *
     * @param errCode 错误码
     * @param errMsg  错误信息
     * @return 响应数据包
     */
    public static PageResponseBean<String> error(String errCode, String errMsg) {
        PageResponseBean<String> result = new PageResponseBean<>();
        result.setSuccess(false);
        result.setErrorCode(errCode);
        result.setMessage(errMsg);
        return result;
    }

    /**
     * 返回错误信息
     *
     * @param errorInfo 错误码+错误信息
     * @return 响应数据包
     */
    public static PageResponseBean<String> error(ErrorInfo errorInfo) {
        PageResponseBean<String> result = new PageResponseBean<>();
        result.setSuccess(false);
        result.setErrorCode(errorInfo.getCode());
        result.setMessage(errorInfo.getMessage());
        return result;
    }

    /**
     * 返回错误信息
     *
     * @param errCode 错误码
     * @param errMsg  错误信息
     * @param data    错误数据
     * @return 响应数据包
     */
    public static <T> PageResponseBean<T> error(String errCode, String errMsg, List<T> data) {
        PageResponseBean<T> result = new PageResponseBean<>();
        result.setSuccess(false);
        result.setErrorCode(errCode);
        result.setMessage(errMsg);
        result.setRows(data);
        return result;
    }


    /**
     * 创建PageResponseBean
     *
     * @param page   分页数据
     * @param mapper 类型转换
     * @param <T>    输入数据类型
     * @param <R>    输出数据类型
     * @return 响应数据
     */
    private static <T, R> PageResponseBean<R> createPageInfo(IPage<T> page, Function<? super T, ? extends R> mapper) {
        //List<R>
        PageResponseBean<R> responseBean = new PageResponseBean<>();
        IPage<R> newPage = page.convert(mapper);
        responseBean.setRows(newPage.getRecords());
        responseBean.setPage(newPage.getCurrent());
        responseBean.setPageSize((int) newPage.getSize());
        responseBean.setTotal(newPage.getTotal());
        responseBean.setPages(newPage.getPages());
        return responseBean;
    }

    /**
     * 创建PageResponseBean
     *
     * @param page 分页数据
     * @param <T>  输出数据类型
     * @return 响应数据
     */
    private static <T> PageResponseBean<T> createPageInfo(IPage<T> page) {
        //List<R>
        PageResponseBean<T> responseBean = new PageResponseBean<>();
        responseBean.setRows(page.getRecords());
        responseBean.setPage(page.getCurrent());
        responseBean.setPageSize((int) page.getSize());
        responseBean.setTotal(page.getTotal());
        responseBean.setPages(page.getPages());
        return responseBean;
    }
}
